package cn.wen.service.impl;

import cn.wen.common.utils.PageUtils;
import cn.wen.common.utils.Query;
import cn.wen.dao.CommentDao;
import cn.wen.entity.CommentEntity;
import cn.wen.entity.GoodsEntity;
import cn.wen.service.CommentService;
import cn.wen.service.GoodsService;
import cn.wen.vo.CommentVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service("commentService")
public class CommentServiceImpl extends ServiceImpl<CommentDao, CommentEntity> implements CommentService {

    @Autowired
    private CommentDao commentDao;

    @Autowired
    private GoodsService goodsService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CommentEntity> page = this.page(
                new Query<CommentEntity>().getPage(params),
                new QueryWrapper<CommentEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 通过创建时间来排序  最新的在上面
     * // 1、先获取楼主的数据
     * // 2、通过楼主的Id一个一个递归解析
     *
     * @param goodsId
     * @return
     */
    @Override
    public List<CommentVO> listCommentByGoodsId(Integer goodsId, String userId) {
        // 获取楼主的数据  通过评论时间来排列
        List<CommentVO> comments = commentDao.findByGoodsIdAndParentCommentNull(goodsId);
        for (CommentVO comment : comments) {
            comment.setInOpen(false);
            comment.setCommentLikeNum(commentDao.getLikeNumberById(comment.getCommentId()));
            comment.setMyUp(commentDao.isLikeByUserId(userId, comment.getCommentId()) != null);
            comment.setReplyComments(commentDao.listTreeComment(comment.getCommentId()));
        }
        return eachComment(comments, userId);
    }

    @Override
    public boolean insertComment(CommentEntity commentEntity) {
        /**
         * 1、判断user_id 和 goods_id 是否为同一个  所以需要判断是否为属于的人
         *      goods_comment 为是否为物品的本人的评论
         * 2、初始化评论点赞
         * 3、初始化评论的各种数据
         */
        // 判断是否为物品是否为自己的评论
        if (checkCommentBelongGoods(commentEntity.getUserId(), commentEntity.getGoodsId())) {
            commentEntity.setGoodsComment(2);
            commentEntity.setOwner(true);
        } else {
            // 客户设置的状态值
            commentEntity.setGoodsComment(1);
            commentEntity.setOwner(false);
        }
        commentEntity.setCommentStatus(1);
        commentEntity.setCreateTime(new Date());
        commentEntity.setCommentLikeNum(0);
        int insert = commentDao.insert(commentEntity);
        return insert > 0;
    }

    /**
     * 判断是否为物品所有者的评论
     * @param userId
     * @param goodsId
     * @return
     */
    private boolean checkCommentBelongGoods(String userId, Integer goodsId) {
        GoodsEntity goodsEntity = goodsService.getGoodsBaseInfoByGoodsId(goodsId);
        if (userId.equals(goodsEntity.getGoodsUserId()) || userId.equals(goodsEntity.getGoodsUserId()))
            return true;
        return false;
    }

    /**
     * 循环每个顶级的评论节点
     *
     * @param comments
     * @return
     */
    private List<CommentVO> eachComment(List<CommentVO> comments, String userId) {
        List<CommentVO> commentsView = new ArrayList<>();
        for (CommentVO comment : comments) {
            CommentVO c = new CommentVO();
            BeanUtils.copyProperties(comment, c);
            // 存储全部的楼主评论
            commentsView.add(c);
        }
        // 合并评论的各层子代到第一级子代集合中
        combineChildren(commentsView, userId);
        return commentsView;
    }

    //存放迭代找出的所有子代的集合
    private List<CommentVO> tempReply = new ArrayList<>();

    /**
     * @param comments root根节点，blog不为空的对象集合
     * @return
     */
    private void combineChildren(List<CommentVO> comments, String userId) {
        for (CommentVO comment : comments) {
            // 获取子列表
            List<CommentVO> replyComments = comment.getReplyComments();
            for (CommentVO replyComment : replyComments) {
                // 循环迭代，找出只子代，将子代存储到当前的二级列表中
                recursively(replyComment, userId);
            }
            // 修改顶级的子节点设置处理过后的数据
            comment.setReplyComments(tempReply);
            // 清空暂存区
            tempReply = new ArrayList<>();
        }

    }

    /**
     * 递归迭代，剥洋葱
     *
     * @param comment 被迭代的对象
     * @return
     */
    private void recursively(CommentVO comment, String userId) {
        beanCopyProperties(comment, userId);
        // 然后判断是否还有子评论 如果存在回复 则再次的调用递归
        if (comment.getReplyComments().size() > 0) {
            List<CommentVO> replyComments = comment.getReplyComments();
            for (CommentVO replyComment : replyComments) {
                beanCopyProperties(replyComment, userId);
                if (replyComment.getReplyComments().size() > 0) {
                    recursively(replyComment, userId);
                }
            }
        }
    }

    private void beanCopyProperties(CommentVO comment, String userId) {
        CommentVO commentOne = new CommentVO();
        BeanUtils.copyProperties(comment, commentOne);
        commentOne.setReplyComments(null);
        commentOne.setCommentLikeNum(commentDao.getLikeNumberById(comment.getCommentId()));
        commentOne.setMyUp(commentDao.isLikeByUserId(userId, comment.getCommentId()) != null);
        // 先将该子回复添加到列表中
        tempReply.add(commentOne);
    }
}